#include "par_tab.h"

/*******************************************************************************
 * @brief  par min get
 * \param[in] par_num : par index,
 * \retval: ok / err
 *******************************************************************************/
uint8_t gp_par_check(uint16_t attr_gp, uint16_t par_num, int32_t par_val)
{
	int32_t MaxVal;
	int32_t MinVal;
	uint16_t attr;

	if (par_num > gp_par_pos(end))
		return 0;
	if (attr_gp >= GP_BASE_MAX)
		return 0;

	attr = gp_par_attr_get(attr_gp, par_num);
	if (attr & PAR_ATTR_NRANG)
		return 1;

	MaxVal = gp_par_max_get(attr_gp, par_num);
	MinVal = gp_par_min_get(attr_gp, par_num);

	if (par_val < MinVal)
		return 0x00;

	if (par_val > MaxVal)
		return 0x00;

	return 0x01;
}

/*******************************************************************************
 * @brief  gp_par correct
 * \param[in] par_num : par index,
 * \retval: value
 *******************************************************************************/
int32_t gp_par_correct(uint16_t attr_gp, uint16_t par_num, int32_t par_val)
{
	int32_t MaxVal;
	int32_t MinVal;
	uint16_t attr;

	if (par_num > gp_par_pos(end))
		return 0;
	if (attr_gp >= GP_BASE_MAX)
		return 0;

	attr = gp_par_attr_get(attr_gp, par_num);
	if (attr & PAR_ATTR_NRANG)
		return par_val;

	MaxVal = gp_par_max_get(attr_gp, par_num);
	MinVal = gp_par_min_get(attr_gp, par_num);

	if (par_val < MinVal)
		par_val = MinVal;

	if (par_val > MaxVal)
		par_val = MaxVal;

	return par_val;
}

/*******************************************************************************
 * @brief  par attr get
 * \param[in] par_num : par index,
 * \retval: attr
 *******************************************************************************/
uint16_t gp_par_attr_get(uint16_t attr_gp, uint16_t par_num)
{
	if (par_num > gp_par_pos(end))
		return (PAR_ATTR_NFUN | PAR_ATTR_END);
	if (attr_gp >= GP_BASE_MAX)
		return 0;

	return gp_par_attr_tab[attr_gp][par_num].attr;
}

/*******************************************************************************
 * @brief  par min get
 * \param[in] par_num : par index,
 * \retval: value
 *******************************************************************************/
int32_t gp_par_min_get(uint16_t attr_gp, uint16_t par_num)
{
	int32_t min;
	uint16_t attr;

	if (par_num > gp_par_pos(end))
		return 0;
	if (attr_gp >= GP_BASE_MAX)
		return 0;

	attr = gp_par_attr_get(attr_gp, par_num);

	if (attr & PAR_ATTR_NRANG)
		return S32_MIN;

	if ((attr & PAR_ATTR_32BIT) && (attr & PAR_ATTR_WHIGH))
		par_num--;

	if (gp_par_attr_tab[attr_gp][par_num].attr & PAR_ATTR_32BIT)
	{
		min = gp_par_attr_tab[attr_gp][par_num].min + gp_par_attr_tab[attr_gp][par_num + 0x01].min * 10000;
	}
	else
	{
		min = gp_par_attr_tab[attr_gp][par_num].min;
	}

	return min;
}

/*******************************************************************************
 * @brief  par max get
 * \param[in] par_num : par index,
 * \retval: value
 *******************************************************************************/
int32_t gp_par_max_get(uint16_t attr_gp, uint16_t par_num)
{
	int32_t max;
	uint16_t attr;

	if (par_num > gp_par_pos(end))
		return 0;
	if (attr_gp >= GP_BASE_MAX)
		return 0;

	attr = gp_par_attr_get(attr_gp, par_num);

	if (attr & PAR_ATTR_NRANG)
		return S32_MAX;

	if ((attr & PAR_ATTR_32BIT) && (attr & PAR_ATTR_WHIGH))
		par_num--;

	if (gp_par_attr_tab[attr_gp][par_num].attr & PAR_ATTR_32BIT)
	{
		max = gp_par_attr_tab[attr_gp][par_num].max + gp_par_attr_tab[attr_gp][par_num + 0x01].max * 10000;
	}
	else
	{
		max = gp_par_attr_tab[attr_gp][par_num].max;
	}

	return max;
}

/*******************************************************************************
 * @brief  par value get
 * \param[in] par_num : par index,
 * \retval: value
 *******************************************************************************/
int32_t gp0_par_get(uint16_t par_num)
{
	return gp_par_get(0, par_num);
}

/*******************************************************************************
 * @brief  par value set
 * \param[in] par_num : par index
 * \param[in] par_val : par value
 * \retval: value
 *******************************************************************************/
int32_t gp0_par_set(uint16_t par_num, int32_t par_val)
{
	return gp_par_set(0, par_num, par_val);
}

/*******************************************************************************
 * @brief  par value get
 * \param[in] par_num : par index,
 * \retval: value
 *******************************************************************************/
int32_t gp_par_get(uint16_t gp, uint16_t par_num)
{
	dword_tt val;

	if (par_num > gp_par_pos(end))
		return 0;

	if (gp >= GP_LIST_MAX)
		return 0;

	if (gp_par_attr_tab[0][par_num].attr & PAR_ATTR_32BIT)
	{
		val.uVal = gp_par_tab(gp)[par_num].uval + (gp_par_tab(gp)[par_num + 0x01].uval << 16);
	}
	else
	{
		val.iVal = gp_par_tab(gp)[par_num].ival;
	}
	return val.iVal;
}

/*******************************************************************************
 * @brief  par value set
 * \param[in] par_num : par index
 * \param[in] par_val : par value
 * \retval: value
 *******************************************************************************/
int32_t gp_par_set_ext(uint16_t gp, uint16_t par_num, int32_t par_val, char save_req)
{
	dword_tt val;
	int32_t src = gp_par_get(gp, par_num);
	uint16_t eep_addr;

	(void)eep_addr;

	if (par_num > gp_par_pos(end))
		return par_val;

	if (gp >= GP_LIST_MAX)
		return 0;

	val.iVal = par_val;

	if (src != par_val)
	{
		if (gp_par_attr_tab[0][par_num].attr & PAR_ATTR_32BIT)
		{
			gp_par_tab(gp)[par_num].uval = val.word.LW.uVal;
			gp_par_tab(gp)[par_num + 0x01].uval = val.word.HW.uVal;

			// save
			if (save_req)
			{
				eep_addr = EEP_GROUP_PAR_BASE + sizeof(gp_par_def_type) * gp + par_num * 2;
				eep_par_save(eep_addr, gp_par_tab(gp)[par_num].uval);
				eep_par_save(eep_addr + 2, gp_par_tab(gp)[par_num + 1].uval);
			}
		}
		else
		{
			gp_par_tab(gp)[par_num].ival = val.iVal;

			// save
			if (save_req)
			{
				eep_addr = EEP_GROUP_PAR_BASE + sizeof(gp_par_def_type) * gp + par_num * 2;
				eep_par_save(eep_addr, gp_par_tab(gp)[par_num].uval);
			}
		}

		if (!save_req)
		{
		}
	}

	return val.iVal;
}

/*******************************************************************************
 * @brief  par value set
 * \param[in] par_num : par index
 * \param[in] par_val : par value
 * \retval: value
 *******************************************************************************/
int32_t gp_par_set(uint16_t gp, uint16_t par_num, int32_t par_val)
{
	return gp_par_set_ext(gp, par_num, par_val, ENA);
}
